<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
        input[type="text"] { width: 300px; }
    </style>
    <script type="text/javascript">
        window.addEventListener('load', function() {
            let clientID;
            let unsubscribed = false;
            let reconnect = true;
            let numFailures = 0;

            function connect() {
                reconnect = true;

                let url = new URL('http://localhost:8000/connection/eventsource');

                const eventSource = new EventSource(url);

                eventSource.onopen = function (e) {
                    numFailures = 0;
                    console.log(e);
                };

                eventSource.onerror = function (e) {
                    numFailures++
                    console.log(e);
                    eventSource.close();
                    if (!reconnect) {
                        return;
                    }
                    setTimeout(function () {
                        drawText("🙏🏾 eventsource: connection reconnecting");
                        connect();
                    }, Math.min(numFailures * 1000, 20000));
                };

                eventSource.onmessage = function (e) {
                    console.log("eventsource: new message");
                    console.log(e);
                    processData(e.data);
                };

                eventSource.addEventListener('ping', function () {
                    drawText('--> ping');
                });
            }

            connect();

            function processData(rawData) {
                if (rawData === "{}") {
                    drawText("--> ping");
                    return
                }
                drawText("--> " + rawData);
                const data = JSON.parse(rawData);
                if (data.connect) {
                    clientID = data.connect.client;
                    let subscriptions = [];
                    const subs = data.connect.subs;
                    if (subs) {
                        for (const m in subs) {
                            if (subs.hasOwnProperty(m)) {
                                subscriptions.push(m);
                            }
                        }
                    }
                    drawText("🟢 connected with client ID " + clientID + " and subscriptions: " + JSON.stringify(subscriptions));
                } else if (data.disconnect) {
                    clientID = null;
                    drawText("🔴 disconnected from a server");
                    const code = data.disconnect.code;
                    reconnect = !((code >= 3500 && code < 4000) || (code >= 4500 && code < 5000));
                } else if (data.unsubscribe) {
                    drawText("🔓 unsubscribed from a channel " + data.channel);
                } else if (data.subscribe) {
                    drawText("🔒 subscribed to a channel " + data.channel);
                } else if (data.pub) {
                    drawText("✨ new data from a channel " + data.channel + ": " + JSON.stringify(data.pub));
                } else {
                    drawText("😟 unsupported push type " + JSON.stringify(data));
                }
            }

            const container = document.getElementById('messages');

            function drawText(text) {
                let e = document.createElement('li');
                e.innerHTML = [(new Date()).toString(), ' ' + text].join(':');
                container.insertBefore(e, container.firstChild);
            }

            window.addEventListener('click', function () {
                // Every click changes status of subscription fetching backend endpoints
                // with current client ID.
                if (unsubscribed) {
                    fetch('subscribe?client=' + clientID);
                } else {
                    fetch('unsubscribe?client=' + clientID);
                }
                unsubscribed = !unsubscribed;
            });
        });
    </script>
</head>
<body>
<ul id="messages"></ul>
</body>
</html>
